# tests/ui/webview_js_runner.py
import webview
import time
import sys
import json
import os
import logging

# 配置日志记录 (可选，但有助于调试)
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 全局变量来存储JS测试结果和控制窗口
js_results_data = None
webview_window = None
stop_event_timeout = 30 # seconds

def run_js_tests_in_webview(html_file_uri, output_json_path):
    global js_results_data, webview_window

    logger.info(f"Creating webview window for: {html_file_uri}")
    webview_window = webview.create_window(
        'JS Test Runner - Isolated',
        html_file_uri,
        width=800,
        height=600,
        hidden=True # 通常在自动化测试中隐藏
    )

    def on_loaded():
        global js_results_data, webview_window
        logger.info("Webview content loaded. Attempting to retrieve JS test results.")
        
        retrieved_results = None
        max_retries = 20 # 增加重试次数和总等待时间
        retry_delay = 0.5  # 秒

        for i in range(max_retries):
            try:
                logger.info(f"Evaluating 'window.jsTestResults' (Attempt {i + 1}/{max_retries})")
                result = webview_window.evaluate_js('window.jsTestResults')
                logger.info(f"Raw JS result: {result}")
                if result is not None: # 确保结果不是 None
                    retrieved_results = result
                    break
                else:
                    logger.warning("'window.jsTestResults' is null, retrying...")
            except Exception as e:
                logger.error(f"Error evaluating 'window.jsTestResults': {e}", exc_info=True)
                retrieved_results = {"error": f"Error evaluating JS: {str(e)}", "passed": 0, "failed": 1, "total": 1}
                break
            time.sleep(retry_delay)

        if retrieved_results is None:
            logger.error("'window.jsTestResults' remained null after all retries.")
            retrieved_results = {"error": "'window.jsTestResults' was not set in the JS environment.", "passed": 0, "failed": 1, "total": 1}

        js_results_data = retrieved_results
        logger.info(f"JS test results obtained: {js_results_data}")

        # 将结果写入JSON文件
        try:
            with open(output_json_path, 'w') as f:
                json.dump(js_results_data, f, ensure_ascii=False)
            logger.info(f"JS test results successfully written to {output_json_path}")
        except IOError as e:
            logger.error(f"Failed to write JS test results to {output_json_path}: {e}", exc_info=True)
            # 如果写入失败，也应该通过某种方式通知主进程，但这里我们主要依赖 pytest 的检查

        if webview_window:
            logger.info("Destroying webview window.")
            webview_window.destroy()

    def on_closed():
        logger.info("Webview window closed.")
        # 如果窗口在结果出来前关闭，确保有一个错误结果
        if js_results_data is None:
            try:
                with open(output_json_path, 'w') as f:
                    json.dump({"error": "Webview window closed prematurely.", "passed": 0, "failed": 1, "total": 1}, f, ensure_ascii=False)
                logger.info(f"Premature close results written to {output_json_path}")
            except IOError as e:
                logger.error(f"Failed to write premature close results to {output_json_path}: {e}", exc_info=True)


    if webview_window:
        webview_window.events.loaded += on_loaded
        webview_window.events.closed += on_closed
        logger.info("Starting webview event loop.")
        webview.start(debug=True) # debug=True有助于诊断
        logger.info("Webview event loop finished.")
    else:
        logger.error("Webview window could not be created.")
        js_results_data = {"error": "Webview window creation failed.", "passed": 0, "failed": 1, "total": 1}
        with open(output_json_path, 'w') as f:
            json.dump(js_results_data, f, ensure_ascii=False)


if __name__ == '__main__':
    if len(sys.argv) < 3:
        logger.error("Usage: python webview_js_runner.py <html_file_uri> <output_json_path>")
        sys.exit(1)

    html_uri = sys.argv[1]
    json_path = sys.argv[2]
    
    logger.info(f"Starting JS test runner script. HTML URI: {html_uri}, Output JSON: {json_path}")

    # 确保输出目录存在
    output_dir = os.path.dirname(json_path)
    if output_dir and not os.path.exists(output_dir):
        try:
            os.makedirs(output_dir)
            logger.info(f"Created output directory: {output_dir}")
        except OSError as e:
            logger.error(f"Failed to create output directory {output_dir}: {e}", exc_info=True)
            # 尝试在当前目录写入
            json_path = os.path.basename(json_path)
            logger.warning(f"Attempting to write output to current directory: {json_path}")


    try:
        run_js_tests_in_webview(html_uri, json_path)
    except Exception as e:
        logger.error(f"Unhandled exception in webview_js_runner: {e}", exc_info=True)
        error_result = {"error": f"Unhandled exception: {str(e)}", "passed": 0, "failed": 1, "total": 1}
        try:
            with open(json_path, 'w') as f:
                json.dump(error_result, f, ensure_ascii=False)
        except IOError:
            logger.error(f"Additionally failed to write unhandled exception to {json_path}")
        sys.exit(1)
    
    logger.info("webview_js_runner.py finished successfully.")
    sys.exit(0)